<template>
  <div class="bg-white my-[10px]">
    <BaseHead>预算明细（单位：万元）</BaseHead>
    <div class="px-[100px] py-[10px] flex">
      <div>预算页扫描件</div>
      <div class="felx-1 ml-[10px]">
        <FileUpload :uploadUrl="uploadUrl" v-model="fileList" @change="fileChange(row)" />
      </div>
    </div>
    <el-table
      :data="budgetList"
      class="w-full"
      border
      stripe
      row-key="id"
      default-expand-all
      :tree-props="{ hasChildren: 'hasChild' }"
      show-summary
      :summary-method="summaryFn"
    >
      <el-table-column type="index" label="序号" width="60px" />
      <el-table-column prop="name" label="预算科目" />
      <el-table-column prop="feeRatio" label="经费占比">
        <template #default="{ row }">
          {{ (row.feeRatio ? row.feeRatio : 0) + "%" }}
        </template></el-table-column
      >
      <el-table-column
        prop="zxMoney"
        :label="[3, 4, 5, 6].includes(budgetType) ? '专项经费' : '预算经费'"
        v-if="[1, 2, 3, 4, 5, 6].includes(budgetType)"
      >
        <template #default="{ row }">
          <div v-if="row.children.length">{{ row.zxMoney }}</div>
          <template v-else>
            <!-- 存在外拨经费时使用change事件 否则使用input事件 主要由于比如留校时5 想输入专项40时 当输入4的时候就会清空留校的值 -->
            <el-input
              v-model="row.zxMoney"
              clearable
              @change="valueChange(row, 'zxMoney', $event)"
              v-if="[4, 6].includes(budgetType)"
            />
            <el-input
              v-model="row.zxMoney"
              clearable
              @input="valueChange(row, 'zxMoney', $event)"
              v-else
            />
          </template>
        </template>
      </el-table-column>
      <el-table-column label="总预算" align="center" v-if="[7, 8].includes(budgetType)">
        <el-table-column prop="zxMoney" label="专项经费">
          <template #default="{ row }">
            <div v-if="row.children.length">{{ row.zxMoney }}</div>
            <el-input
              v-model="row.zxMoney"
              clearable
              @change="valueChange(row, 'zxMoney', $event)"
              v-else
            />
          </template>
        </el-table-column>
        <el-table-column prop="ptMoney" label="配套经费">
          <template #default="{ row }">
            <div v-if="row.children.length">{{ row.ptMoney }}</div>
            <el-input
              v-model="row.ptMoney"
              clearable
              @input="valueChange(row, 'ptMoney', $event)"
              v-else
            />
          </template>
        </el-table-column>
      </el-table-column>
      <el-table-column prop="ptMoney" label="配套经费" v-if="[3, 5].includes(budgetType)">
        <template #default="{ row }">
          <div v-if="row.children.length">{{ row.ptMoney }}</div>
          <el-input
            v-model="row.ptMoney"
            clearable
            @input="valueChange(row, 'ptMoney', $event)"
            v-else
          />
        </template>
      </el-table-column>
      <el-table-column label="专项预算拆分" align="center" v-if="[4, 6, 7, 8].includes(budgetType)">
        <el-table-column prop="lxMoney" label="留校专项">
          <template #default="{ row }">
            <div v-if="row.children.length">{{ row.lxMoney }}</div>
            <el-input
              v-model="row.lxMoney"
              clearable
              @input="lxValueChange(row, 'lxMoney', $event)"
              v-else
            />
          </template>
        </el-table-column>
        <el-table-column prop="wbMoney" label="外拨专项（合计）">
          <template #default="{ row }">
            <div>{{ row.wbMoney }}</div>
          </template>
        </el-table-column>
      </el-table-column>
      <el-table-column prop="zcMoney" label="自筹经费" v-if="[2, 5, 6, 8].includes(budgetType)">
        <template #default="{ row }">
          <div v-if="row.children.length">{{ row.zcMoney }}</div>
          <el-input
            v-model="row.zcMoney"
            clearable
            @input="valueChange(row, 'zcMoney', $event)"
            v-else
          />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import BaseHead from "@/views/project/components/BaseHead.vue";
import FileUpload from "@/views/project/components/FileUpload.vue";
import { budgetDetail, editBudget } from "@/api/project/zx/lxxm";
import { fomateNumber, fiexdNumber } from "@/utils/main";
import { ElMessage } from "element-plus";
const uploadUrl = `/commonFile/uploadFile?modelName=纵向项目立项预算扫描件`;
const operateId = ref(null);
const budgetList = ref([]);
const zxFee = ref(0); //专项经费
const selfProvideFee = ref(0); //自筹经费(拨款)
const outFee = ref(0); //外拨经费
const attachFee = ref(0); //配套经费（学校资助经费）
const fileList = ref([]); //文件集合
const totalFee = computed(() => {
  return zxFee.value + selfProvideFee.value + attachFee.value;
});
let fileIds = ""; //文件id
const isAuditor = inject("isAuditor");
const taskId = inject("taskId");
const checkStatus = inject("checkStatus");
const budgetType = computed(() => {
  //只有专项经费
  if (selfProvideFee.value == 0 && outFee.value == 0 && attachFee.value == 0) {
    return 1;
  }
  //专项经费和拨款金额（自筹）
  if (selfProvideFee.value > 0 && outFee.value == 0 && attachFee.value == 0) {
    return 2;
  }
  //专项经费和学校资助经费（配套）
  if (selfProvideFee.value == 0 && outFee.value == 0 && attachFee.value > 0) {
    return 3;
  }
  //专项经费和外拨经费
  if (selfProvideFee.value == 0 && outFee.value > 0 && attachFee.value == 0) {
    return 4;
  }
  //专项经费和拨款金额（自筹）和学校资助经费（配套）
  if (selfProvideFee.value > 0 && outFee.value == 0 && attachFee.value > 0) {
    return 5;
  }
  //专项经费和拨款金额（自筹）和外拨经费
  if (selfProvideFee.value > 0 && outFee.value > 0 && attachFee.value == 0) {
    return 6;
  }
  //专项经费和学校资助经费（配套）和外拨经费
  if (selfProvideFee.value == 0 && outFee.value > 0 && attachFee.value > 0) {
    return 7;
  }
  //全部都有
  if (selfProvideFee.value > 0 && outFee.value > 0 && attachFee.value > 0) {
    return 8;
  }
});
//获取预算信息详情
const getBudgetDetail = async () => {
  const params = {
    proId: operateId.value,
  };
  try {
    const res = await budgetDetail(params);
    budgetList.value = res.data.bizProjectBudgetFeeList || [];
    const proInitOtherBaseInfoVo = res.data.proInitOtherBaseInfoVo;
    zxFee.value = parseFloat(proInitOtherBaseInfoVo.feeAuthorize);
    selfProvideFee.value = parseFloat(proInitOtherBaseInfoVo.selfProvideFee);
    outFee.value = parseFloat(proInitOtherBaseInfoVo.outFee);
    attachFee.value = parseFloat(proInitOtherBaseInfoVo.attachFee);
    //金额字符串类型转数字类型 根据填写的预算金额类型设置各项金额的值
    const moneyToNumber = (rows) => {
      for (let i = 0; i < rows.length; i++) {
        rows[i].zxMoney = parseFloat(rows[i].zxMoney);
        rows[i].ptMoney = attachFee.value > 0 ? parseFloat(rows[i].ptMoney) : 0;
        rows[i].lxMoney =
          outFee.value > 0 ? parseFloat(rows[i].lxMoney) : parseFloat(rows[i].zxMoney);
        rows[i].wbMoney = outFee.value > 0 ? parseFloat(rows[i].wbMoney) : 0;
        rows[i].zcMoney = selfProvideFee.value > 0 ? parseFloat(rows[i].zcMoney) : 0;
        rows[i].feeRatio = rows[i].feeRatio ? parseFloat(rows[i].feeRatio) : 0;
        if (rows[i].children) {
          moneyToNumber(rows[i].children);
        }
      }
    };
    moneyToNumber(budgetList.value);
    budgetList.value = updateParentMoney(budgetList.value);
    console.log(budgetList.value);
    const fileArray = proInitOtherBaseInfoVo.fileInfos || [];
    fileArray.forEach((item) => {
      fileList.value.push({
        id: item.fileId,
        name: item.fileName,
      });
    });
  } catch (error) {
    console.log(error);
  }
};
//编辑
const edit = async (id) => {
  operateId.value = id;
  getBudgetDetail();
};
//更新节点数据
const updateParentMoney = (nodes) => {
  return nodes.map((node) => {
    // 如果有子节点，则递归处理子节点
    if (node.children && node.children.length > 0) {
      const updatedChildren = updateParentMoney(node.children);
      //专项
      const sumZxFee = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.zxMoney ? parseFloat(cur.zxMoney) : 0);
      }, 0);
      // 配套
      const sumPtFee = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.ptMoney ? parseFloat(cur.ptMoney) : 0);
      }, 0);
      //留校
      const sumLxFee = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.lxMoney ? parseFloat(cur.lxMoney) : 0);
      }, 0);
      //外拨
      const sumWbFee = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.wbMoney ? parseFloat(cur.wbMoney) : 0);
      }, 0);
      //自筹
      const sumZcFee = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.zcMoney ? parseFloat(cur.zcMoney) : 0);
      }, 0);
      const sumFeeRatio = updatedChildren.reduce((acc, cur) => {
        return acc + (cur.feeRatio ? parseFloat(cur.feeRatio) : 0);
      }, 0);
      return {
        ...node,
        zxMoney: fiexdNumber(sumZxFee, 6),
        ptMoney: fiexdNumber(sumPtFee, 6),
        lxMoney: fiexdNumber(sumLxFee, 6),
        wbMoney: fiexdNumber(sumWbFee, 6),
        zcMoney: fiexdNumber(sumZcFee, 6),
        feeRatio: fiexdNumber(sumFeeRatio),
        children: updatedChildren,
      };
    }
    // 没有子节点则直接返回
    return node;
  });
};
//输入的专项经费、配套经费、自筹经费改变 更新经费占比
const valueChange = (row, feeType, val) => {
  fomateNumber(row, feeType, val);
  if (!row[feeType]) {
    row[feeType] = 0;
  }
  nextTick(() => {
    if (feeType == "zxMoney") {
      //如果总外拨经费不等0 才计算外拨专项的值
      if (outFee.value != 0) {
        //判断专项经费是否大于配套经费
        if (parseFloat(row[feeType]) < parseFloat(row.lxMoney)) {
          ElMessage({
            message: "留校专项不能大于专项经费!",
            type: "error",
          });
          //将留校专项置为0
          row.lxMoney = 0;
        }
        row.wbMoney = row[feeType] - row.lxMoney;
      } else {
        //总外拨经费为0时留校经费等于专项经费
        row.lxMoney = row[feeType];
      }
    }
    row.feeRatio =
      Math.round(
        ((parseFloat(row.zxMoney) + parseFloat(row.ptMoney) + parseFloat(row.zcMoney)) /
          totalFee.value) *
          10000
      ) / 100;
    budgetList.value = updateParentMoney(budgetList.value);
  });
};
// 留校经费改变 不更新经费占比
const lxValueChange = (row, feeType, val) => {
  fomateNumber(row, feeType, val);
  if (!row[feeType]) {
    row[feeType] = 0;
  }
  nextTick(() => {
    if (parseFloat(row[feeType]) > parseFloat(row.zxMoney)) {
      ElMessage({
        message: "留校专项不能大于专项经费!",
        type: "error",
      });
      row[feeType] = 0;
    }
    row.wbMoney = row.zxMoney - row[feeType];
    budgetList.value = updateParentMoney(budgetList.value);
  });
};
//合计方法
const summaryFn = ({ columns, data }) => {
  const sums = [];
  let countTotal = 0;
  columns.forEach((column, index) => {
    if (index == 0) {
      sums[index] = "";
    } else if (index == 1) {
      sums[index] = "合计";
    } else {
      let total = 0;
      data.forEach((item) => {
        total += parseFloat(item[column.property]);
      });
      if (["zxMoney", "ptMoney", "zcMoney"].includes(column.property)) {
        countTotal += total;
      }
      if (index == 2) {
        sums[index] = fiexdNumber(total) + "%";
      } else {
        sums[index] = fiexdNumber(total, 6);
      }
    }
  });
  //如果输入的经费合计等于总经费 则经费占比置为100 防止出现100.1% 这类情况
  if (fiexdNumber(countTotal, 6) == totalFee.value) {
    sums[2] = "100%";
  }
  return sums;
};
const emit = defineEmits(["save-success", "save-ok"]);
//保存
const save = async (submitType) => {
  try {
    //判断预算信息是否为空
    if (!budgetList.value.length) {
      ElMessage({
        message: "请填写预算信息！",
        type: "error",
      });
      return;
    }
    let zxTotal = 0; //专项（预算）经费
    let ptTotal = 0; //配套总经费
    let zcTotal = 0; //自筹总经费
    let wbTotal = 0; //外拨总经费
    budgetList.value.forEach((item) => {
      zxTotal += parseFloat(item.zxMoney);
      ptTotal += parseFloat(item.ptMoney);
      zcTotal += parseFloat(item.zcMoney);
      wbTotal += parseFloat(item.wbMoney);
    });
    //判断预算经费合计是否与总经费相等
    if (fiexdNumber(zxTotal, 6) != zxFee.value) {
      ElMessage({
        message: "预算经费合计与总预算经费不相等！",
        type: "error",
      });
      return;
    }
    //判断配套经费合计需等于项目信息中的配套经费！
    if (fiexdNumber(ptTotal, 6) != attachFee.value) {
      ElMessage({
        message: "配套经费合计需等于项目信息中的配套经费！",
        type: "error",
      });
      return;
    }
    //判断自筹经费合计需等于项目信息中的自筹经费！
    if (fiexdNumber(zcTotal, 6) != selfProvideFee.value) {
      ElMessage({
        message: "自筹经费合计需等于项目信息中的自筹经费！",
        type: "error",
      });
      return;
    }
    //判断外拨经费合计需等于项目信息中的外拨经费！
    if (fiexdNumber(wbTotal, 6) != outFee.value) {
      ElMessage({
        message: "外拨经费合计需等于项目信息中的外拨经费！",
        type: "error",
      });
      return;
    }
    const bizProjectBudgetFee = [];
    const getParams = (rows) => {
      for (let i = 0; i < rows.length; i++) {
        const baseObj = {
          budgetStandardId: rows[i].standardId,
          feeRatio: rows[i].feeRatio,
          subjectCode: rows[i].code,
          subjectId: rows[i].id,
          projectId: operateId.value,
        };
        bizProjectBudgetFee.push(
          Object.assign({}, baseObj, { budgetType: "zhuanxiang", subjectFee: rows[i].zxMoney })
        );
        bizProjectBudgetFee.push(
          Object.assign({}, baseObj, { budgetType: "liuxiao", subjectFee: rows[i].lxMoney })
        );
        bizProjectBudgetFee.push(
          Object.assign({}, baseObj, { budgetType: "waibo", subjectFee: rows[i].wbMoney })
        );
        bizProjectBudgetFee.push(
          Object.assign({}, baseObj, { budgetType: "peitao", subjectFee: rows[i].ptMoney })
        );
        bizProjectBudgetFee.push(
          Object.assign({}, baseObj, { budgetType: "ziChou", subjectFee: rows[i].zcMoney })
        );
        if (rows[i].children) {
          getParams(rows[i].children);
        }
      }
    };
    getParams(budgetList.value);
    //判断预算经费合计是否与总经费相等
    let params = {
      bizProjectBudgetBatch: {
        budgetFee: totalFee.value, //预算总金额
        budgetFileId: fileIds, //预算页扫描件ID
        budgetStandardId: bizProjectBudgetFee[0].budgetStandardId,
        projectClass: "zXProject",
        projectId: operateId.value, //项目id
        submitType,
        isAuditor: isAuditor.value,
        taskId: taskId.value,
        checkstatus: checkStatus.value,
      },
      bizProjectBudgetFee,
    };
    const res = await editBudget(params);
    if (res.code === 200) {
      emit("save-success");
    }
  } catch (error) {
    console.log(error);
  } finally {
    emit("save-ok");
  }
};
defineExpose({ edit, save });
//上传附件改变
const fileChange = () => {
  const ids = fileList.value.map((item) => {
    const id = item.response ? item.response.data : item.id;
    return id;
  });
  fileIds = ids.join(",");
};
</script>

<style scoped lang="scss"></style>
